#ifndef _MPZQFORM_INCLUDE_
#define _MPZQFORM_INCLUDE_

/*
    Copyright 2009-2010 Andrew V. Sutherland

    This file is part of "smoothrelation".

    smoothrelation is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    smoothrelation is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with smoothrelation.  If not, see <http://www.gnu.org/licenses/>.
*/

// note that D < 0 and L=floor(|D|^{1/4})

int mpz_sqrt_modprime (mpz_t o, mpz_t a, mpz_t p);

void mpz_qform_discriminant (mpz_t D, mpz_t a, mpz_t b, mpz_t c);
int mpz_qform_valid_discriminant (mpz_t D);
static inline int mpz_qform_is_id2 (mpz_t a, mpz_t b, mpz_t D) { return (mpz_cmp_ui(a,1)==0); }

int mpz_qform_reduce (mpz_t a, mpz_t b, mpz_t c);
int mpz_qform_square (mpz_t u3, mpz_t v3, mpz_t w3, mpz_t u, mpz_t v, mpz_t w, mpz_t L);
int mpz_qform_compose (mpz_t u3, mpz_t v3, mpz_t w3, mpz_t u1, mpz_t v1, mpz_t w1, mpz_t u2, mpz_t v2, mpz_t w2, mpz_t L);

void mpz_qform_set_id2 (mpz_t a, mpz_t b, mpz_t D);
void mpz_qform_c2 (mpz_t c, mpz_t a, mpz_t b, mpz_t D);
int mpz_qform_primeform2 (mpz_t a, mpz_t b, mpz_t p, mpz_t D);
int mpz_qform_reduce2 (mpz_t a, mpz_t b, mpz_t D);
int mpz_qform_square2 (mpz_t a3, mpz_t b3, mpz_t a1, mpz_t b1, mpz_t D, mpz_t L);
int mpz_qform_compose2 (mpz_t a3, mpz_t b3, mpz_t a1, mpz_t b1, mpz_t a2, mpz_t b2, mpz_t D, mpz_t L, int reduce);
void mpz_qform_invert2 (mpz_t a, mpz_t b, mpz_t D);
void mpz_qform_exp2 (mpz_t a2, mpz_t b2, mpz_t a1, mpz_t b1, unsigned long e, mpz_t D, mpz_t L);

#endif
